package cn.doitedu.javase.socket.demo5;

import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import org.apache.commons.io.FileUtils;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;

public class _01_http服务器 {

    public static void main(String[] args) throws IOException {

        // 启动服务，绑定8080端口
        ServerSocket serverSocket = new ServerSocket(8080);

        // 循环等待新的请求
        while (true) {

            // 收到请求，建立连接
            Socket socket = serverSocket.accept();

            // 获取网络输入、输出 字节流
            InputStream is = socket.getInputStream();
            OutputStream os = socket.getOutputStream();

            // 将 输入字节流，包装成 缓冲字符流
            BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));

            /**
             * 解析http请求协议
             */
            // 读取客户端发过来的http请求，里面的第一行
            String requestFirstLine = br.readLine();  //GET /login.html HTTP/1.1

            // /login.html?a=3&b=4
            String requestUrlAndParam = requestFirstLine.split(" ")[1];
            String[] split = requestUrlAndParam.split("\\?");

            // 解析出请求的url
            String requestUrl = split[0];  // /login.html

            // 解析出请求中附带的参数
            HashMap<String, String> paramMap = new HashMap<>();
            if (split.length > 1) {
                String params = split[1]; // a=3&b=4&c=5
                String[] split1 = params.split("&");

                // a=3
                for (String s : split1) {
                    String[] pair = s.split("=");
                    String param_name = pair[0];
                    String param_value = pair[1];
                    paramMap.put(param_name, param_value);
                }
            }

            // 读取请求中剩余的行，但不做任何解析
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
                if (line.equals("")) break;
            }


            /**
             * 根据浏览器所请求的url不同，来做不同的响应
             */
            if (requestUrl.equals("/") || requestUrl.equals("/index.html")) {

                // 给浏览器返回一个首页面的html代码
                String html = FileUtils.readFileToString(new File("html/index.html"), "UTF-8");

                // 拼接响应行、响应头、响应体
                String response =
                        "HTTP/1.1 200 OK\n" +  // 响应行
                                "Content-Type:text/html;charset=UTF-8\n" +  // 响应头
                                "\n" +  // 空行
                                html;  // 响应体

                // 将响应发给浏览器
                os.write(response.getBytes(StandardCharsets.UTF_8));

                os.flush();
                os.close();
                is.close();
                socket.close();
            } else if (requestUrl.equals("/favicon.ico")) {

                // 构造一个文件字节流，用来读取图片文件
                FileInputStream fileInputStream = new FileInputStream("html/favicon.ico");

                // 拼接响应头
                String responseHeader =
                        "HTTP/1.1 200 OK\n" +  // 响应行
                                "Accept-Ranges:bytes\n" +  // 响应头
                                "Content-Type:image/x-icon\n" + // 响应头
                                "\n";
                // 一、先发送出去响应头
                os.write(responseHeader.getBytes(StandardCharsets.UTF_8));

                // 二、再继续发送响应体
                byte[] bytes = new byte[1024];
                int read;
                // 循环，一边读图片文件里面的字节，一边通过网络流发给浏览器
                while ((read = fileInputStream.read(bytes)) != -1) {
                    // 用网络输出流，输出读到的字节
                    os.write(bytes, 0, read);
                }

                fileInputStream.close();
                os.close();
                is.close();
                socket.close();
            } else if (requestUrl.equals("/login.html")) {

                // 读文件
                String htmlCode = FileUtils.readFileToString(new File("html/login.html"), StandardCharsets.UTF_8);

                // 拼接http响应
                String response =
                        "HTTP/1.1 200 OK\n" +  // 响应行
                                "Content-Type:text/html;charset=UTF-8\n" +  // 响应头
                                "\n" +  // 空行
                                htmlCode;  // 响应体

                // 发给浏览器
                os.write(response.getBytes(StandardCharsets.UTF_8));
                os.close();
                is.close();
                socket.close();

            } else if (requestUrl.equals("/user_login")) {
                System.out.println(requestUrl);
                System.out.println(paramMap.get("user_name"));
                System.out.println(paramMap.get("password"));


                // 读文件
                String htmlCode = FileUtils.readFileToString(new File("html/user_home.html"), StandardCharsets.UTF_8);

                // 拼接http响应
                String response =
                        "HTTP/1.1 200 OK\n" +  // 响应行
                                "Content-Type:text/html;charset=UTF-8\n" +  // 响应头
                                "\n" +  // 空行
                                htmlCode;  // 响应体
                // 发给浏览器
                os.write(response.getBytes(StandardCharsets.UTF_8));
                os.close();
                is.close();
                socket.close();

            }else if(requestUrl.equals("/calc.html")){

                // 读文件
                String htmlCode = FileUtils.readFileToString(new File("html/calc.html"), StandardCharsets.UTF_8);

                // 拼接http响应
                String response =
                        "HTTP/1.1 200 OK\n" +  // 响应行
                                "Content-Type:text/html;charset=UTF-8\n" +  // 响应头
                                "\n" +  // 空行
                                htmlCode;  // 响应体
                // 发给浏览器
                os.write(response.getBytes(StandardCharsets.UTF_8));
                os.close();
                is.close();
                socket.close();

            }else if(requestUrl.equals("/niubi")){

                String a = paramMap.get("a");
                String b = paramMap.get("b");
                String c = paramMap.get("c");
                // 浏览器发过来的带特殊字符的信息，都会做urlEncode编码
                String expressionEncoded = paramMap.get("expression");
                // 所以，要先按urlDecode解码才能得到用户填写的信息
                String expStr = URLDecoder.decode(expressionEncoded);

                // 进行表达式运算
                Expression expression = AviatorEvaluator.compile(expStr);

                HashMap<String, Object> dataMap = new HashMap<>();
                dataMap.put("a",Integer.parseInt(a));
                dataMap.put("b",Integer.parseInt(b));
                dataMap.put("c",Integer.parseInt(c));
                Object res = expression.execute(dataMap);

                // 响应体
                // {"result":55}
                String responseBodyJson = "{\"result\":"+res+"}";

                // 拼接http响应
                String response =
                        "HTTP/1.1 200 OK\n" +  // 响应行
                                "Content-Type:application/json\n" +  // 响应头
                                "\n" +  // 空行
                                responseBodyJson;  // 响应体
                // 发给浏览器
                os.write(response.getBytes(StandardCharsets.UTF_8));
                os.close();
                is.close();
                socket.close();



            }
        }
    }
}
